package com.icesoft.core.web.suppose.safehttp.service.impl;

import cn.hutool.core.io.FileUtil;
import com.icesoft.core.common.util.KeyPairUtils;
import com.icesoft.core.common.util.MD5Util;
import com.icesoft.core.common.util.PemFileUtils;
import com.icesoft.core.web.helper.PathUtil;
import com.icesoft.core.web.model.CryptoKeyPair;
import com.icesoft.core.web.suppose.safehttp.SafeRequestConst;
import com.icesoft.core.web.suppose.safehttp.service.ICryptoKeyPairRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.security.KeyPair;
import java.util.Base64;

@ConditionalOnProperty(name = "icesoft.safe.sm-crypto-enable", havingValue = "false", matchIfMissing = true)
@Configuration
@Slf4j
class RsaKeyAutoReadOrCreateBean {
    private static final String DEFAULT_KEY_PATH = "key/rsaKeyPair.pem";

    RsaKeyAutoReadOrCreateBean(ICryptoKeyPairRepository cryptoKeyPairRepository) {
        KeyPair defaultKeyPair = readOrCreateKeyPair(PathUtil.getProjectRootPath() + DEFAULT_KEY_PATH);
        String defaultKeyId = MD5Util.md5(defaultKeyPair.getPrivate().getEncoded());
        CryptoKeyPair cryptoKeyPair = new CryptoKeyPair();
        cryptoKeyPair.setPublicKey(Base64.getEncoder().encodeToString(defaultKeyPair.getPublic().getEncoded()));
        cryptoKeyPair.setPrivateKey(Base64.getEncoder().encodeToString(defaultKeyPair.getPrivate().getEncoded()));
        cryptoKeyPair.setKeyId(defaultKeyId);
        cryptoKeyPair.setAlgorithm(SafeRequestConst.ALGORITHM_COMMON);
        cryptoKeyPairRepository.saveKey(cryptoKeyPair);
    }

    private static KeyPair readOrCreateKeyPair(String keyFilePath) {
        KeyPair keyPair;
        if (FileUtil.exist(keyFilePath)) {
            try {
                keyPair = PemFileUtils.readKeyPair(keyFilePath);
                log.info("密钥文件加载成功：{}", keyFilePath);
            } catch (IOException e) {
                log.error("pem文件读取错误", e);
                throw new IllegalArgumentException("密钥文件读取失败：" + keyFilePath);
            }
        } else {
            try {
                keyPair = KeyPairUtils.createKeyPair();
                PemFileUtils.writeKeyPairToFile(keyFilePath, keyPair);
                log.info("密钥文件生成成功：{}", keyFilePath);
            } catch (IOException e) {
                log.error("密钥生成错误", e);
                throw new RuntimeException(e);
            }
        }
        return keyPair;
    }
}